package com.iretailer.report.config;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @author xjw
 * @date 2018/5/9
 */
public class ThreadManager {

    //锁对象
    private static final Object lockObj = new Object();
    private static volatile Map<String, ThreadPoolExecutor> threadPoolMap = new HashMap<>();

    public static ThreadPoolExecutor getThreadPoolProxy(final String threadPoolName, final Integer corPoolSize, final Integer maximumPoolSize) {
        ThreadPoolExecutor tpp = threadPoolMap.get(threadPoolName);
        if (tpp == null) {
            synchronized (lockObj) {
                tpp = threadPoolMap.get(threadPoolName);
                if (tpp == null) {
//                  tpp = new ThreadPoolExecutor(corPoolSize,maximumPoolSize,60L,TimeUnit.SECONDS,
//                          new SynchronousQueue<Runnable>(), new DefaultThreadFactory(threadPoolName));
                    tpp = new ThreadPoolExecutor(corPoolSize, maximumPoolSize, 60L, TimeUnit.SECONDS,
                            new ArrayBlockingQueue<Runnable>(4000),
                            new DefaultThreadFactory(threadPoolName),
                            new ThreadPoolExecutor.CallerRunsPolicy());
                    threadPoolMap.put(threadPoolName, tpp);
                }
            }
        }
        return tpp;
    }

    public static ThreadPoolExecutor getSystemThreadPool() {
        return ThreadManager.getThreadPoolProxy("System", 0, 50);
    }


    static class DefaultThreadFactory implements ThreadFactory {
        //        private static final AtomicInteger poolNumber = new AtomicInteger(1);
        private final ThreadGroup group;
        private final AtomicInteger threadNumber = new AtomicInteger(1);
        private final String namePrefix;

        DefaultThreadFactory(String name) {
            SecurityManager s = System.getSecurityManager();
            group = (s != null) ? s.getThreadGroup() :
                    Thread.currentThread().getThreadGroup();
            namePrefix = "pool-" +
                    name +
                    "-thread-";
        }

        @Override
        public Thread newThread(Runnable r) {
            Thread t = new Thread(group, r,
                    namePrefix + threadNumber.getAndIncrement(),
                    0);
            if (t.isDaemon()) {
                t.setDaemon(false);
            }
            if (t.getPriority() != Thread.NORM_PRIORITY) {
                t.setPriority(Thread.NORM_PRIORITY);
            }
            return t;
        }
    }
}
